﻿using System;
using agsXMPP;
using agsXMPP.protocol.client;
using AlphaMobileControls;
using Lapd.Common;
using Lapd.Common.Helpers;
using Lapd.Relative.Resources;

namespace Lapd.Relative
{
    public partial class Main : AlphaForm
    {
        #region Members

        private XmppClientConnection _xmppClientConnection;

        /// <summary>
        /// GPS Latitude. Sample value: 36.681930 (my house)
        /// </summary>
        private double _latitude;
            
        /// <summary>
        /// GPS Longitude. Sample value: -4.451755 (my house)
        /// </summary>
        private double _longitude;

        #endregion

        #region Constructors

        public Main()
        {
            InitializeComponent();

            // Initialize alpha controls ---------------------------------------------
            HelpAlarmPicture.Image =       AlphaImage.CreateFromResource("Lapd.Relative.Resources.008_Reminder_32x42_72.png");
            LocationAlarmPicture.Image =   AlphaImage.CreateFromResource("Lapd.Relative.Resources.brujula_39x32.png");
            OkPicture.Image =              AlphaImage.CreateFromResource("Lapd.Relative.Resources.112_Tick_Green_32x32_72.png");
            ErrorPicture.Image =           AlphaImage.CreateFromResource("Lapd.Relative.Resources.109_AllAnnotations_Error_32x32_72.png");
            WarningOkPicture.Image =       AlphaImage.CreateFromResource("Lapd.Relative.Resources.QuestionBlue_20x33.png");
            LocationWarningPicture.Image = AlphaImage.CreateFromResource("Lapd.Relative.Resources.base_map_32x32.png");
            // --------------------------------------------------------------------------

            _xmppClientConnection = InitializeXmppClientConnection();

            // 1.- Login
            ServiceDdsHelper.Login(Session.Server, Session.UserName, Session.Domain, Session.Password, ref _xmppClientConnection);
        }

        #endregion

        #region Error events

        private void XmppCon_OnStreamError(object sender, agsXMPP.Xml.Dom.Element e)
        {
#if DEBUG
            StatusLabel.Text = String.Format(Messages.Error_Stream, e);
#else
            StatusLabel.Text = Messages.Error_Generic;
#endif
        }

        private void XmppCon_OnSocketError(object sender, Exception ex)
        {
#if DEBUG
            StatusLabel.Text = String.Format(Messages.Error_Socket, ex);
#else
            StatusLabel.Text = Messages.Error_Generic;
#endif
        }

        #endregion

        #region Xmpp events

        private void XmppCon_OnLogin(object sender)
        {
            if (InvokeRequired)
            {
                // Windows Forms are not Thread Safe, we need to invoke this :(
                // We're not in the UI thread, so we need to call BeginInvoke				
                BeginInvoke(new ObjectHandler(XmppCon_OnLogin), new object[] { sender });
                return;
            }

            ProcessOnLogin();

        }

        void XmppCon_OnMessage(object sender, Message msg)
        {
            if (InvokeRequired)
            {
                // Windows Forms are not Thread Safe, we need to invoke this :(
                // We're not in the UI thread, so we need to call BeginInvoke				
                BeginInvoke(new MessageHandler(XmppCon_OnMessage), new object[] { sender, msg });
                return;
            }

            string instanceName = ServiceDdsHelper.GetInstanceName(msg);

            switch (instanceName)
            {
                case ServiceDdsConstants.ALARM_TOPIC_INSTANCE_NAME:
                    
                    ProcessAlarmTopic();

                    break;
                case ServiceDdsConstants.WARNING_RESPONSE_TOPIC_INSTANCE_NAME:

                    ProcessWarningResponseTopic(msg);

                    break;
                case ServiceDdsConstants.LOCATION_ALARM_TOPIC_INSTANCE_NAME:

                    ProcessLocationAlarmTopic();
                    
                    break;
                case ServiceDdsConstants.LOCATION_RESPONSE_TOPIC_INSTANCE_NAME:

                    ProcessLocationResponseTopic(msg);

                    break;
                default:

                    break;
            }
        }

        #endregion

        #region UI events

        private void WarningOkMenuItem_Click(object sender, EventArgs e)
        {
            CleanForm();
            ProcessWarningOkRequest();
        }

        private void LocationRequestMenuItem_Click(object sender, EventArgs e)
        {
            CleanForm();
            ProcessLocationRequest();
        }

        private void WarningOkButtonClick(object sender, EventArgs e)
        {
            CleanForm();
            ProcessWarningOkRequest();
        }

        private void LocationWarningButton_Click(object sender, EventArgs e)
        {
            CleanForm();
            ProcessLocationRequest();
        }

        private void ExitMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void CleanMenuItem_Click(object sender, EventArgs e)
        {
            CleanForm();
        }

        #endregion

        #region Private methods

        private XmppClientConnection InitializeXmppClientConnection()
        {
            XmppClientConnection xmppClientConnection = new XmppClientConnection();

            xmppClientConnection.OnLogin += new ObjectHandler(XmppCon_OnLogin);
            xmppClientConnection.OnSocketError += new ErrorHandler(XmppCon_OnSocketError);
            xmppClientConnection.OnStreamError += new XmppElementHandler(XmppCon_OnStreamError);
            xmppClientConnection.OnMessage += new MessageHandler(XmppCon_OnMessage);

            return xmppClientConnection;
        }

        private void EnableForm()
        {
            stbMain.Text = Messages.Status_Connected;
            MenuItem.Enabled = true;
            WarningOkMenuItem2.Enabled = true;
            WarningOkButton.Enabled = true;
            LocationWarningButton.Enabled = true;
        }

        private void ProcessAlarmTopic()
        {
            CleanForm();
            HelpAlarmPicture.Visible = true;
            StatusLabel.Text = Messages.Alarm_HelpActivated;
        }

        private void ProcessWarningResponseTopic(Message msg)
        {
            string responseValue = ServiceDdsHelper.GetWarningResponseValue(msg);

            switch (responseValue)
            {
                case (ServiceDdsConstants.WARNING_RESPONSE_TOPIC_OK):
                    StatusLabel.Text = Messages.WarningOk_OkResponse;
                    OkPicture.Visible = true;
                    ErrorPicture.Visible = false;
                    break;
                case (ServiceDdsConstants.WARNING_RESPONSE_TOPIC_KO):
                    StatusLabel.Text = Messages.WarningOk_KoResponse;
                    ErrorPicture.Visible = true;
                    OkPicture.Visible = false;
                    break;
                default:
                    break;
            }
        }

        private void ProcessLocationAlarmTopic()
        {
            CleanForm();
            LocationAlarmPicture.Visible = true;
            StatusLabel.Text = Messages.AlarmLocation_OutOfPerimeter;
        }

        private void ProcessLocationResponseTopic(Message msg)
        {
            ServiceDdsHelper.GetLatitudeAndLongitude(msg, out _latitude, out _longitude);

            // Open an Internet Explorer with Google Maps and the location selected
            string locationUrl = GoogleMapsHelper.GetUrlByLatitudeAndLongitude(_latitude, _longitude);
            Map map = new Map(locationUrl);
            map.Show();
        }

        private void ProcessOnLogin()
        {
            try
            {
                ServiceDdsHelper.InitializeServiceDDS(ref _xmppClientConnection);
                EnableForm();
            }
            catch (Exception)
            {
                StatusLabel.Text = Messages.Error_Generic;
            }
        }

        private void ProcessWarningOkRequest()
        {
            StatusLabel.Text = Messages.WarningOk_Request;

            // Send 
            IQ iq = ServiceDdsHelper.WriteOnTopic(
                ServiceDdsConstants.WARNING_REQUEST_TOPIC_INSTANCE_NAME,
                ref _xmppClientConnection,
                long.Parse(Session.UserId),
                ServiceDdsConstants.WARNING_REQUEST_TOPIC_OK);

            if (iq == null)
            {
                StatusLabel.Text = Messages.Error_Generic;
            }
            else
            {
                StatusLabel.Text = Messages.WarningOk_RequestSent;
            }
        }

        private void ProcessLocationRequest()
        {
            IQ iq = ServiceDdsHelper.WriteOnTopic(
                ServiceDdsConstants.LOCATION_REQUEST_TOPIC_INSTANCE_NAME,
                ref _xmppClientConnection,
                long.Parse(Session.UserId),
                ServiceDdsConstants.LOCATION_REQUEST_TOPIC_WHERE_ARE_YOU);

            if (iq == null)
            {
                StatusLabel.Text = Messages.Error_Generic;
            }
            else
            {
                StatusLabel.Text = Messages.WarningLocation_RequestSent;
            }
        }

        private void CleanForm()
        {
            HelpAlarmPicture.Visible = false;
            LocationAlarmPicture.Visible = false;
            StatusLabel.Text = String.Empty;
            OkPicture.Visible = false;
            ErrorPicture.Visible = false;
        }

        #endregion
       
    }
}